package cn.edu.buaa.treehole.controller;

import cn.edu.buaa.treehole.pojo.network.SimpleResponseInfo;
import cn.edu.buaa.treehole.pojo.network.user.*;
import cn.edu.buaa.treehole.service.SignatureService;
import cn.edu.buaa.treehole.service.TimeService;
import cn.edu.buaa.treehole.service.UserService;
import cn.edu.buaa.treehole.service.exception.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.support.RequestHandledEvent;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Controller
@CrossOrigin
@RequestMapping("/user")
public class UserController {
    private final UserService userService;
    private final SignatureService signatureService;
    private final TimeService timeService;

    @Autowired
    public UserController(UserService userService, SignatureService signatureService, TimeService timeService) {
        this.userService = userService;
        this.signatureService = signatureService;
        this.timeService = timeService;
    }

    @RequestMapping("/sign_up")
    @ResponseBody
    public SimpleResponseInfo signup(@RequestBody UserSignUpRequestInfo info) {
        SimpleResponseInfo out = new SimpleResponseInfo();
        System.out.println(info.getEmail()+info.getPassword()+info.getDefaultSignature());
        out.setTime(timeService.nowTime());

        try {
            userService.addUser(info);
            out.setStatus("success");
        } catch (SignatureTooLongException e) {
            out.setStatus("signature_wrong");
        } catch (PasswordTooLongException e) {
            out.setStatus("password_wrong");
        } catch (EmailTooLongException e) {
            out.setStatus("email_wrong");
        } catch (EmailUsedException e) {
            out.setStatus("email_used");
        } catch (Exception e) {
            out.setStatus("exception");
        }

        return out;
    }

    @RequestMapping("/login")
    @ResponseBody
    public SimpleResponseInfo login(
            @RequestBody UserLoginRequestInfo info,
            HttpSession session,
            HttpServletRequest request,
            HttpServletResponse response) {
        SimpleResponseInfo out = new SimpleResponseInfo();
        out.setTime(timeService.nowTime());
        try {
            userService.login(info, session, request, response);
            out.setStatus("success");
        } catch (PasswordWrongException e) {
            out.setStatus("wrong");
        } catch (Exception e) {
            out.setStatus("exception");
        }
        return out;
    }

    @RequestMapping("/logout")
    @ResponseBody
    public SimpleResponseInfo logout(
            HttpSession session,
            HttpServletRequest request,
            HttpServletResponse response) {
        SimpleResponseInfo out = new SimpleResponseInfo();
        out.setTime(timeService.nowTime());
        try {
            userService.logout(session, request, response);
            out.setStatus("success");
        } catch (Exception e) {
            out.setStatus("exception");
        }
        return out;
    }

    @RequestMapping("/change_info")
    @ResponseBody
    public SimpleResponseInfo changeInfo(
            @RequestBody UserChangeInfoRequestInfo info,
            HttpSession session,
            HttpServletRequest request) {
        SimpleResponseInfo out = new SimpleResponseInfo();

        out.setTime(timeService.nowTime());

        try {
            long uid = userService.loginCheck(request, session);
            userService.change_info(uid, info);
            out.setStatus("success");
        } catch (SignatureTooLongException e) {
            out.setStatus("signature_wrong");
        } catch (NeedLoginException e) {
            out.setStatus("need_login");
        } catch (PasswordWrongException e) {
            out.setStatus("password_wrong");
        } catch (PasswordTooLongException e) {
            out.setStatus("password_long");
        } catch (Exception e) {
            out.setStatus("exception");
        }
        return out;
    }

    @RequestMapping("/get_signature")
    @ResponseBody
    public String getSignature(
            @RequestBody UserSignatureRequestInfo info,
            HttpSession session,
            HttpServletRequest request) {
        JSONObject out = new JSONObject();

        try {
            out.put("time",timeService.nowTime());
            long uid = userService.loginCheck(request, session);
            if (info.getType().equals("default")) {
                out.put("signature", userService.getDefaultSignature(uid));
            }
            else if (info.getType().equals("certain")) {
                out.put("signature", signatureService.getUsedSignatureForPost(uid, info.getPid()));
            }
            else {
                out.put("signature", signatureService.getUsedSignatureForUser(uid));
            }
            out.put("status", "success");
        } catch (NeedLoginException e) {
            try {
                out.put("status", "need_login");
            } catch (JSONException ignored) { }
        }
        catch (Exception e) {
            try {
                out.put("status", "exception");
            } catch (JSONException ignored) { }
        }
        return out.toString();
    }

    @RequestMapping("/delete_signature")
    @ResponseBody
    public SimpleResponseInfo deleteSignature(
            @RequestBody UserDeleteSignatureRequestInfo info,
            HttpSession session,
            HttpServletRequest request) {
        SimpleResponseInfo out = new SimpleResponseInfo();

        out.setTime(timeService.nowTime());

        try {
            long uid = userService.loginCheck(request, session);
            signatureService.deleteSignatureForUser(uid, info.getPid(), info.getSignature());
            out.setStatus("success");
        } catch (NeedLoginException e) {
            out.setStatus("need_login");
        } catch (Exception e) {
            out.setStatus("exception");
        }
        return out;
    }
}
